# -*- coding: utf-8 -*-

import json
import logging
import os
import uuid
from datetime import datetime
from odoo import http
from odoo.http import request

_logger = logging.getLogger(__name__)


class FileUploadController(http.Controller):
    """简单文件上传控制器"""

    @http.route('/api/upload', type='http', auth='none', methods=['POST', 'OPTIONS'], csrf=False)
    def upload_file(self, **kwargs):
        """
        文件上传接口
        
        使用方法:
        POST /api/upload
        Content-Type: multipart/form-data
        
        参数:
        - file: 要上传的文件
        
        返回:
        {
            "code": 200,
            "msg": "上传成功",
            "data": {
                "fileName": "原始文件名",
                "fileUrl": "访问URL"
            }
        }
        """
        # 设置CORS响应头的通用函数
        def add_cors_headers(response):
            response.headers['Access-Control-Allow-Origin'] = '*'
            response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
            response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With, Accept, Origin, Cache-Control'
            response.headers['Access-Control-Max-Age'] = '86400'
            return response

        # 处理OPTIONS预检请求
        if request.httprequest.method == 'OPTIONS':
            response = request.make_response('')
            return add_cors_headers(response)

        try:
            # 设置CORS响应
            def make_response(data, status=200):
                response = request.make_response(
                    json.dumps(data, ensure_ascii=False) if data else '',
                    headers=[('Content-Type', 'application/json; charset=utf-8')]
                )
                response.status_code = status
                return add_cors_headers(response)

            # 获取上传的文件
            uploaded_file = request.httprequest.files.get('file')
            if not uploaded_file:
                return make_response({
                    'code': 400,
                    'msg': '请选择要上传的文件',
                    'data': None
                }, 400)

            # 检查文件名
            if not uploaded_file.filename:
                return make_response({
                    'code': 400,
                    'msg': '文件名不能为空',
                    'data': None
                }, 400)

            # 获取项目根目录
            project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
            
            # 创建file目录
            file_dir = os.path.join(project_root, 'file')
            os.makedirs(file_dir, exist_ok=True)
            
            # 按日期创建子目录
            today = datetime.now().strftime('%Y%m%d')
            upload_dir = os.path.join(file_dir, today)
            os.makedirs(upload_dir, exist_ok=True)

            # 生成唯一文件名
            file_ext = os.path.splitext(uploaded_file.filename)[1]
            unique_id = str(uuid.uuid4())
            timestamp = datetime.now().strftime('%H%M%S')
            unique_filename = f"{timestamp}_{unique_id}{file_ext}"

            # 保存文件
            file_path = os.path.join(upload_dir, unique_filename)
            with open(file_path, 'wb') as f:
                uploaded_file.save(f)

            # 生成访问URL
            base_url = request.httprequest.host_url.rstrip('/')
            file_url = f"{base_url}/file/{today}/{unique_filename}"

            return make_response({
                'code': 200,
                'msg': '上传成功',
                'data': {
                    'fileName': uploaded_file.filename,
                    'fileUrl': file_url
                }
            })

        except Exception as e:
            _logger.error(f"文件上传异常: {str(e)}", exc_info=True)
            # 确保异常情况下也返回正确的CORS头
            return make_response({
                'code': 500,
                'msg': f'文件上传失败: {str(e)}',
                'data': None
            }, 500)

    @http.route('/file/<path:file_path>', type='http', auth='public', methods=['GET', 'OPTIONS'], csrf=False)
    def get_file(self, file_path, **kwargs):
        """
        访问上传的文件
        
        使用方法:
        GET /file/{date}/{filename}
        
        返回: 文件内容
        """
        # 处理OPTIONS预检请求
        if request.httprequest.method == 'OPTIONS':
            response = request.make_response('')
            response.headers['Access-Control-Allow-Origin'] = '*'
            response.headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS'
            response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With, Accept, Origin'
            response.headers['Access-Control-Max-Age'] = '86400'
            return response

        try:
            # 获取项目根目录
            project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
            
            # 构建完整文件路径
            full_file_path = os.path.join(project_root, 'file', file_path)
            
            # 安全检查：确保文件路径在file目录内
            file_dir = os.path.join(project_root, 'file')
            if not os.path.commonpath([full_file_path, file_dir]) == file_dir:
                return request.make_response(
                    json.dumps({'code': 403, 'msg': '非法访问路径'}, ensure_ascii=False),
                    headers=[('Content-Type', 'application/json; charset=utf-8')]
                )

            # 检查文件是否存在
            if not os.path.exists(full_file_path):
                return request.make_response(
                    json.dumps({'code': 404, 'msg': '文件不存在'}, ensure_ascii=False),
                    headers=[('Content-Type', 'application/json; charset=utf-8')]
                )

            # 读取文件
            with open(full_file_path, 'rb') as f:
                file_content = f.read()

            # 获取MIME类型
            import mimetypes
            mime_type = mimetypes.guess_type(full_file_path)[0] or 'application/octet-stream'

            # 对于图片、视频等媒体文件，使用inline显示；其他文件使用attachment下载
            inline_types = ['image/', 'video/', 'audio/']
            disposition = 'inline' if any(mime_type.startswith(t) for t in inline_types) else 'attachment'

            # 返回文件
            response = request.make_response(
                file_content,
                headers=[
                    ('Content-Type', mime_type),
                    ('Content-Disposition', f'{disposition}; filename="{os.path.basename(full_file_path)}"'),
                    ('Content-Length', str(len(file_content))),
                    ('Cache-Control', 'public, max-age=3600'),  # 缓存1小时
                ]
            )
            
            # 添加CORS头
            response.headers['Access-Control-Allow-Origin'] = '*'
            return response

        except Exception as e:
            _logger.error(f"文件访问异常: {str(e)}", exc_info=True)
            response = request.make_response(
                json.dumps({'code': 500, 'msg': f'文件访问失败: {str(e)}'}, ensure_ascii=False),
                headers=[('Content-Type', 'application/json; charset=utf-8')]
            )
            response.headers['Access-Control-Allow-Origin'] = '*'
            return response
